﻿using Bing.Maps;
using Callisto.Controls;
using DT.GoogleAnalytics.Metro;
using RWSBeeldbank.Common;
using RWSBeeldbank.Data;
using RWSBeeldbank.Utility;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using Windows.ApplicationModel.DataTransfer;
using Windows.ApplicationModel.Resources;
using Windows.ApplicationModel.Store;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.Capture;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.UI.Notifications;
using Windows.UI.Popups;
using Windows.UI.StartScreen;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
using RWSBeeldbank.DataModel;
using Windows.UI.Core;

// The Item Detail Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234232

namespace RWSBeeldbank
{
    /// <summary>
    /// A page that displays details for a single item within a group while allowing gestures to
    /// flip through other items belonging to the same group.
    /// </summary>
    public sealed partial class VideoDetailPage : LayoutAwarePage
    {
        public bool mapButtonWasJustPressed = false;

        public VideoDetailPage()
        {
            this.InitializeComponent();
            this.flipView.SelectionChanged += FlipView_SelectionChanged;
        }

        /// <summary>
        /// Populates the page with content passed during navigation.  Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        /// <param name="navigationParameter">The parameter value passed to
        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.
        /// </param>
        /// <param name="pageState">A dictionary of state preserved by this page during an earlier
        /// session.  This will be null the first time a page is visited.</param>
        protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
        {
            // Allow saved page state to override the initial item to display
            if (pageState != null && pageState.ContainsKey("SelectedItem"))
            {
                navigationParameter = pageState["SelectedItem"];
            }

            var item = MediaObjectDataSource.GetItem((String)navigationParameter);

            if (item != null)
            {
                this.DefaultViewModel["Group"] = item.Group;
                this.DefaultViewModel["Items"] = item.Group.Items;
                this.flipView.SelectedItem = item;
            }

            // Deregister the DataRequested event handler when the handler was already added
            // This can happen when the app restarts itself after settings were changed by the user
            if (_dataRequestHandler != null)
                DataTransferManager.GetForCurrentView().DataRequested -= _dataRequestHandler;

            // Set the handler to the actual event handler method
            _dataRequestHandler = OnDataRequested;

            // Register for DataRequested event
            DataTransferManager.GetForCurrentView().DataRequested += _dataRequestHandler;
        }

        /// <summary>
        /// Preserves state associated with this page in case the application is suspended or the
        /// page is discarded from the navigation cache.  Values must conform to the serialization
        /// requirements of <see cref="SuspensionManager.SessionState"/>.
        /// </summary>
        /// <param name="pageState">An empty dictionary to be populated with serializable state.</param>
        protected override void SaveState(Dictionary<String, Object> pageState)
        {
            var selectedItem = (MediaObjectDataItem)this.flipView.SelectedItem;
            if (selectedItem != null)
                pageState["SelectedItem"] = selectedItem.UniqueId;

            // Deregister the DataRequested event handler
            DataTransferManager.GetForCurrentView().DataRequested -= OnDataRequested;

            // Dispose the handler so it can be added when LoadState fires again
            _dataRequestHandler = null;
        }

        void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
        {
            var request = args.Request;
            var item = (MediaObjectDataItem)this.flipView.SelectedItem;

            // Fill request with MediaObject Data
            request = Tools.SetMessageRequest(item, request);
        }

        private async void OnBrowseToMediaObjectButtonClicked(object sender, RoutedEventArgs e)
        {
            var item = (MediaObjectDataItem)this.flipView.SelectedItem;
            // Create the URI to launch from a string. 
            var uri = new Uri(item.DirectLink);

            // Launch the URI. 
            await Windows.System.Launcher.LaunchUriAsync(uri); 
        }

        private async void OnPinMediaObjectButtonClicked(object sender, RoutedEventArgs e)
        {
            var item = (MediaObjectDataItem)this.flipView.SelectedItem;
            var uniqueId = item.UniqueId.Replace("|", "_");
            var activationString = item.TypeId.ToString() + "|" + item.UniqueId;
            var uri = await Tools.GetUriLocalImageAsync(item.TileImagePath.AbsoluteUri, uniqueId);

            var tile = new SecondaryTile(
                    uniqueId,                        // Tile ID
                    item.AltTitle,                   // Tile short name
                    item.Title,                      // Tile display name
                    activationString,                // Activation argument
                    TileOptions.ShowNameOnLogo,      // Tile options
                    uri                              // Tile logo URI
                );

            await tile.RequestCreateAsync();
        }

        private async void OnDownloadMediaObjectButtonClicked(object sender, RoutedEventArgs e)
        {
            // Retrieve the video and store it in the local VideosLibrary
            var item = (MediaObjectDataItem)this.flipView.SelectedItem;
            await Tools.StoreVideoInVideosLibraryAsync(item);
            await MediaObjectDataSource.SetRatingAsync(4, item.Id);
            PageAppBar.IsOpen = false;
        }

 

        private async void flipView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // Retrieve the current image
            var item = (MediaObjectDataItem)this.flipView.SelectedItem;

            // Work around to make shure element is always filled
            //
            // http://social.msdn.microsoft.com/Forums/windowsapps/en-US/f2b768bc-c999-44b1-b539-bfba4ab3969b/problem-with-asyc-method-cant-figure-out-how-to-solve-the-errors
            // http://social.msdn.microsoft.com/Forums/windowsapps/en-US/e15d4852-a601-4bd6-88b4-42480fd71e70/win-rt-awaiting-the-dispatcherrunasync
            FrameworkElement element = null;
            await Dispatcher.RunAsync(CoreDispatcherPriority.Low, async () =>
            {
                element = flipView.ItemContainerGenerator.ContainerFromIndex(this.flipView.SelectedIndex) as FrameworkElement;

                if (element != null)
                {
                    var rate = element.FindDescendantByName("rate") as Rating;
                    var mapButton = element.FindDescendantByName("mapButton") as Button;

                    var AlreadyRatedBorder = element.FindDescendantByName("AlreadyRated") as TextBlock;
                    if (AlreadyRatedBorder != null)
                    {
                        AlreadyRatedBorder.Text = "";
                    }

                    if (rate != null)
                    {
                        // Try to get the rating for this item from the file
                        rate.Value = Convert.ToDouble(await Utility.Tools.getItemRating(item.Id));

                        // If there wasn't a rating in the file, use the rating that came with the JSON feed
                        // IMPORTANT for testing, set item caching to 0 
                        if (rate.Value == -1 && !item.Rating.Equals(""))
                        {
                            rate.Value = Convert.ToDouble(item.Rating);
                        }
                    }

                    if (mapButton != null)
                    {
                        if ((myMapTop != null))
                        {
                            if ((item.Latitude != 0.0))
                            {
                                mapButton.Visibility = Visibility.Visible;
                            }
                            else
                            {
                                mapButton.Visibility = Visibility.Collapsed;
                            }
                        }
                    }
                }
            });

            if (item != null && (myMapTop != null) && (item.Latitude != 0.0))
            {
                // Creating a location object, this is used to set the location of the pin and center the map
                Bing.Maps.Location locationTop = new Bing.Maps.Location
                {
                    Latitude = item.Latitude,
                    Longitude = item.Longitude
                };

                Bing.Maps.Location location = new Bing.Maps.Location
                {
                    Latitude = item.Latitude,
                    Longitude = item.Longitude
                };

                // Set the map to be centered on that location
                myMapTop.SetView(location, item.GoogleZoom);

                // Create a pushpin and reposition it on the map at location
                MapLayer.SetPosition(pushPin, location);
            }

            AnalyticsHelper.TrackPageView(pageRoot.ToString());
        }

        private async void rate_Tapped(object sender, TappedRoutedEventArgs e)
        {
            // Retrieve the current image
            var item = (MediaObjectDataItem)this.flipView.SelectedItem;
            Rating rating = sender as Rating;

            if (!await Tools.isItemRated(item.Id))
            {
                await MediaObjectDataSource.SetRatingAsync(item.Id, Convert.ToInt32(rating.Value));
            }
            else
            {
                var element = flipView.ItemContainerGenerator.ContainerFromIndex(this.flipView.SelectedIndex) as FrameworkElement;
                var AlreadyRatedBorder = element.FindDescendantByName("AlreadyRated") as TextBlock;
                AlreadyRatedBorder.Text = Constants.RATINGALREADYRATED + rating.Value.ToString() + Constants.RATINGALREADYRATED2;
            }
        }

        private void flipView_Tapped(object sender, TappedRoutedEventArgs e)
        {
            if (mapButtonWasJustPressed == false)
            {
                myMapTop.Visibility = Visibility.Collapsed;
            }
            mapButtonWasJustPressed = false;
        }

        private void mapButton_Click(object sender, RoutedEventArgs e)
        {
            mapButtonWasJustPressed = true;
            myMapTop.Visibility = Visibility.Visible;
        }

    }
}
